/**
 * Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.stylefeng.guns.weixin.preview;

import cn.hutool.core.io.IoUtil;
import cn.hutool.system.SystemUtil;
import cn.stylefeng.guns.core.util.VideoFileTypeUtil;
import cn.stylefeng.guns.weixin.common.FileTypeJudge;
import cn.stylefeng.guns.weixin.common.SpringContextHolder;
import cn.stylefeng.roses.kernel.file.api.constants.FileConstants;
import cn.stylefeng.roses.kernel.file.api.exception.FileException;
import cn.stylefeng.roses.kernel.file.api.exception.enums.FileExceptionEnum;
import cn.stylefeng.roses.kernel.file.api.expander.FileConfigExpander;
import cn.stylefeng.roses.kernel.file.api.pojo.props.LocalFileProperties;
import cn.stylefeng.roses.kernel.file.api.pojo.request.SysFileInfoRequest;
import cn.stylefeng.roses.kernel.file.api.pojo.response.SysFileInfoResponse;
import cn.stylefeng.roses.kernel.file.api.util.PdfFileTypeUtil;
import cn.stylefeng.roses.kernel.file.api.util.PicFileTypeUtil;
import cn.stylefeng.roses.kernel.file.modular.entity.SysFileInfo;
import cn.stylefeng.roses.kernel.file.modular.service.SysFileInfoService;
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource;
import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource;
import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 通用控制器
 */
@RestController
@Slf4j
@ApiResource(name = "通用控制器")
public class RestSystemWxController {

    private static SysFileInfoService sysFileInfoService = SpringContextHolder.getBean(SysFileInfoService.class);





    /**
     * 上传文件
     *
     * @author jizhonbao
     * @date 2021/12/03
     */
    @PostResource(name = "上传文件", path = "/wx/uploadImg", requiredPermission = false, requiredLogin = false)
    public ResponseData upload(@RequestPart("file") MultipartFile file) throws IOException {

        SysFileInfoRequest sysFileInfoRequest = new SysFileInfoRequest();
        sysFileInfoRequest.setSecretFlag("N");
        SysFileInfoResponse fileUploadInfoResult = sysFileInfoService.uploadFile(file, sysFileInfoRequest);

        File uploadFile = new File(this.getFilePath(fileUploadInfoResult.getFileId()));
        int fileType = FileTypeJudge.isFileType(FileTypeJudge.getType(new FileInputStream(uploadFile)));
        if (fileType == 7) {
            sysFileInfoService.removeById(fileUploadInfoResult.getFileId());
            uploadFile.delete();
            return new ErrorResponseData("500", "文件格式错误");

        }
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("fileId", fileUploadInfoResult.getFileId());
        dataMap.put("fileUrl", getFileUrl(fileUploadInfoResult.getFileId()));
        return new SuccessResponseData(dataMap);
    }



    /**
     * 公有文件预览
     *
     * @author majianguo
     * @date 2020/12/27 13:17
     */
    @GetResource(name = "公有文件预览", path = "wx" + FileConstants.FILE_PUBLIC_PREVIEW_URL, requiredPermission = false, requiredLogin = false)
    public void publicPreview(@Validated(SysFileInfoRequest.detail.class) SysFileInfoRequest sysFileInfoRequest) {

        HttpServletResponse response = HttpServletUtil.getResponse();
        sysFileInfoRequest.setSecretFlag(YesOrNotEnum.N.getCode());

        // 根据文件id获取文件信息结果集
        SysFileInfoResponse sysFileInfoResponse = sysFileInfoService.getFileInfoResult(sysFileInfoRequest.getFileId());

        // 如果文件加密等级不符合，文件不允许被访问
        if (!sysFileInfoRequest.getSecretFlag().equals(sysFileInfoResponse.getSecretFlag())) {
            throw new FileException(FileExceptionEnum.FILE_DENIED_ACCESS);
        }

        // 获取文件后缀
        String fileSuffix = sysFileInfoResponse.getFileSuffix().toLowerCase();

        // 获取文件字节码
        byte[] fileBytes = sysFileInfoResponse.getFileBytes();
        // 如果文件后缀是图片或者pdf，则直接输出流
        if (PicFileTypeUtil.getFileImgTypeFlag(fileSuffix)
                || PdfFileTypeUtil.getFilePdfTypeFlag(fileSuffix)
                || VideoFileTypeUtil.getFileVideoTypeFlag(fileSuffix)) {
            try {
                // 设置contentType
                if (PicFileTypeUtil.getFileImgTypeFlag(fileSuffix)) {
                    response.setContentType(MediaType.IMAGE_PNG_VALUE);
                } else if (PdfFileTypeUtil.getFilePdfTypeFlag(fileSuffix)) {
                    response.setContentType(MediaType.APPLICATION_PDF_VALUE);
                } else if (VideoFileTypeUtil.getFileVideoTypeFlag(fileSuffix)) {
                    response.setContentType("video/mp4");
                }

                // 获取outputStream
                ServletOutputStream outputStream = response.getOutputStream();

                // 输出字节流
                IoUtil.write(outputStream, true, fileBytes);
            } catch (IOException e) {
                throw new FileException(FileExceptionEnum.WRITE_BYTES_ERROR, e.getMessage());
            }
        } else {
            // 不支持别的文件预览
            throw new FileException(FileExceptionEnum.PREVIEW_ERROR_NOT_SUPPORT);
        }
    }

    /**
     * 获取图片地址
     *
     * @param fileId fileId
     * @return String
     */
    public static String getFileUrl(Long fileId) {
        // 获取context-path
        SysFileInfo sysFileInfo = sysFileInfoService.getById(fileId);
        String contextPath = HttpServletUtil.getRequest().getContextPath();
        return FileConfigExpander.getServerDeployHost() + contextPath + "/tempFilePath/defaultBucket/" + sysFileInfo.getFileObjectName();
    }

    public String getFilePath(Long fileId) {
        SysFileInfo sysFileInfo = sysFileInfoService.getById(fileId);
        String currentSavePath;
        LocalFileProperties localFileProperties = new LocalFileProperties();
        if (SystemUtil.getOsInfo().isWindows()) {
            currentSavePath = localFileProperties.getLocalFileSavePathWin();
        } else {
            currentSavePath = "/data/tempFilePath";
        }
        return currentSavePath + "/" + sysFileInfo.getFileBucket() + "/" + sysFileInfo.getFileObjectName();
    }


}
